package com.musicsonar.android.utils;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.xml.sax.InputSource;
import org.xmlpull.v1.XmlSerializer;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.util.Log;
import android.util.Xml;
import android.widget.Toast;

import com.facebook.android.AsyncFacebookRunner;
import com.facebook.android.FacebookError;
import com.facebook.android.SessionStore;
import com.musicsonar.android.bean.PlayList;
import com.musicsonar.android.bean.Song;
import com.musicsonar.android.dialog.MusicSonarDialog;

public class MusicSonarUtils {

	/**
	 * Function to convert milliseconds time to Timer Format
	 * Hours:Minutes:Seconds
	 * */
	public static String milliSecondsToTimer(long milliseconds) {
		String finalTimerString = "";
		String secondsString = "";

		// Convert total duration into time
		int hours = (int) (milliseconds / (1000 * 60 * 60));
		int minutes = (int) (milliseconds % (1000 * 60 * 60)) / (1000 * 60);
		int seconds = (int) ((milliseconds % (1000 * 60 * 60)) % (1000 * 60) / 1000);
		// Add hours if there
		if (hours > 0) {
			finalTimerString = hours + ":";
		}

		// Prepending 0 to seconds if it is one digit
		if (seconds < 10) {
			secondsString = "0" + seconds;
		} else {
			secondsString = "" + seconds;
		}

		finalTimerString = finalTimerString + minutes + ":" + secondsString;

		// return timer string
		return finalTimerString;
	}

	/**
	 * Function to convert milliseconds time to Timer Format
	 * Hours:Minutes:Seconds
	 * */
	public static long TimerToMilliSeconds(CharSequence timer) {
		return TimerToMilliSeconds(timer.toString());
	}

	/**
	 * Function to convert milliseconds time to Timer Format
	 * Hours:Minutes:Seconds
	 * */
	public static long TimerToMilliSeconds(String timer) {
		String[] parts = timer.split(":");
		long total = 0;
		if(parts.length == 3){
			int hoursToSecond = Integer.parseInt(parts[0]) * 60 * 60;
			int minutesToSecond = Integer.parseInt(parts[1]) * 60;
			int second = Integer.parseInt(parts[2]);
			total = hoursToSecond + minutesToSecond + second;
		}else{
			int minutesToSecond = Integer.parseInt(parts[0]) * 60;
			int second = Integer.parseInt(parts[1]);
			total = minutesToSecond + second;
		}

		// return total seconds
		return total;
	}

	/**
	 * Function to get Progress percentage
	 * 
	 * @param currentDuration
	 * @param totalDuration
	 * */
	public static int getProgressPercentage(long currentDuration, long totalDuration) {
		Double percentage = (double) 0;

		long currentSeconds = (int) (currentDuration / 1000);
		long totalSeconds = (int) (totalDuration / 1000);

		// calculating percentage
		percentage = (((double) currentSeconds) / totalSeconds) * 100;

		// return percentage
		return percentage.intValue();
	}

	/**
	 * Function to change progress to timer
	 * 
	 * @param progress
	 *            -
	 * @param totalDuration
	 *            returns current duration in milliseconds
	 * */
	public static int progressToTimer(int progress, int totalDuration) {
		int currentDuration = 0;
		totalDuration = (int) (totalDuration / 1000);
		currentDuration = (int) ((((double) progress) / 100) * totalDuration);

		// return current duration in milliseconds
		return currentDuration * 1000;
	}

	public static org.w3c.dom.Document XMLfromString(String xml) throws Exception {
		org.w3c.dom.Document doc = null;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		DocumentBuilder db = dbf.newDocumentBuilder();
		InputSource is = new InputSource();
		is.setCharacterStream(new StringReader(xml));
		is.setEncoding("UTF-8");
		doc = db.parse(is);

		return doc;
	}

	public static Bitmap loadBitmap(String fileUrl, boolean saveImage) {
		URL myFileUrl = null;
		String imageName = getImageID(fileUrl) + ".jpg";
		File imageFile = new File(MusicSonarConstant.MEDIA_PATH + imageName);
		if(imageFile.exists()){
			return BitmapFactory.decodeFile(MusicSonarConstant.MEDIA_PATH + imageName);
		}
		try {
			myFileUrl = new URL(fileUrl);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		}
		try {
			HttpURLConnection conn = (HttpURLConnection) myFileUrl.openConnection();
			conn.setDoInput(true);
			conn.connect();
			InputStream is = conn.getInputStream();

			Bitmap bmImg = BitmapFactory.decodeStream(is);
			if(saveImage){
				FileOutputStream out = new FileOutputStream(MusicSonarConstant.MEDIA_PATH + imageName);
				bmImg.compress(Bitmap.CompressFormat.JPEG, 100, out);
			}
			return bmImg;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public static String getImageID(String url){
		return url.substring("http://i.ytimg.com/vi/".length(), url.length()).split("/")[0];
	}

	public static boolean isOnline(Context c) {
		ConnectivityManager cm = (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
		NetworkInfo ni = cm.getActiveNetworkInfo();
		if (ni != null && ni.isConnected()){
			return true;
		}else{
			return false;
		}
	}

	public static Long getAccountID(String accountName, String facebookID){
		Long result = new Long(0);
		HttpURLConnection conn = null;
		try{
			URL url = new URL(MusicSonarConstant.GET_ACCOUNT_ID_URL_LINK);
			conn = (HttpURLConnection) url.openConnection();
			conn.setUseCaches(false);
			conn.setDoInput(true);
			conn.setDoOutput(true);
			conn.setRequestMethod("POST");
	
			DataOutputStream wr = new DataOutputStream (conn.getOutputStream());
			wr.writeBytes("username="+accountName+"&facebookID="+facebookID);
			wr.flush();
			wr.close();
			InputStream is = conn.getInputStream();
			BufferedReader rd = new BufferedReader(new InputStreamReader(is));
			String line;
			StringBuffer response = new StringBuffer(); 
			while((line = rd.readLine()) != null) {
				response.append(line);
			}
			rd.close();
			result = new Long(response.toString().trim());
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if(conn != null) {
				conn.disconnect(); 
			}
		}

		return result;
	}

	public static boolean savePlayListOnServer(){
		HttpURLConnection conn = null;
		try {
			PlayList playList = SongsManager.getActualPlayList();
			String xmlString = convertToXMLString(playList);

			List<NameValuePair> pairs = new ArrayList<NameValuePair>();
			pairs.add(new BasicNameValuePair("userID", MusicSonarConstant.accountID.toString()));
			pairs.add(new BasicNameValuePair("name", playList.getName()));
			pairs.add(new BasicNameValuePair("code", (playList.getSaved().booleanValue() ? playList.getCode().toString() : "-1")));
			pairs.add(new BasicNameValuePair("xml", xmlString));
			HttpClient httpClient = new DefaultHttpClient();
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(pairs,HTTP.UTF_8);
			HttpPost post = new HttpPost(MusicSonarConstant.SAVE_PLAYLIST_URL_LINK);
			post.setEntity(entity);
			HttpResponse response = httpClient.execute(post);
			HttpEntity resEntity = response.getEntity();
			playList.setCode(new Long(EntityUtils.toString(resEntity)));
			playList.setSaved(Boolean.TRUE);
			SongsManager.savePlayList(playList.getSongList());
			return true;
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(conn != null) {
				conn.disconnect(); 
			}
		}
		return false;
	}

	public static List<PlayList> getSendedList(Long accountID){
		List<PlayList> result = new ArrayList<PlayList>();
		return result;
	}

	public static void getFacebookSessionInformation(final Context context){
		MusicSonarConstant.mAsyncRunner = new AsyncFacebookRunner(MusicSonarConstant.mFacebook);

        SessionStore.restore(MusicSonarConstant.mFacebook, context);
        Bundle params = new Bundle();
        params.putString("fields", "name, picture, location");
        MusicSonarConstant.mAsyncRunner.request("me", params, new AsyncFacebookRunner.RequestListener(){
            public void onFacebookError(FacebookError e, final Object state) {
                Toast.makeText(context, "Facebook Error: " + e.getMessage(),  Toast.LENGTH_LONG).show();
            }

            public void onFileNotFoundException(FileNotFoundException e, final Object state) {
            	Toast.makeText(context, "Facebook Error: " + e.getMessage(),  Toast.LENGTH_LONG).show();
            }

            public void onIOException(IOException e, final Object state) {
            	Toast.makeText(context, "Facebook Error: " + e.getMessage(),  Toast.LENGTH_LONG).show();
            }

            public void onMalformedURLException(MalformedURLException e, final Object state) {
            	Toast.makeText(context, "Facebook Error: " + e.getMessage(),  Toast.LENGTH_LONG).show();
            }

            public void onComplete(final String response, final Object state) {
            	JSONObject jsonObject;
                try {
                    jsonObject = new JSONObject(response);

                    final String picURL = jsonObject.getString("picture");
                    //final String name = jsonObject.getString("name");
                    final String userUID = jsonObject.getString("id");

                    MusicSonarConstant.facebookUID = !"null".equals(userUID) ? userUID : null;
                    MusicSonarConstant.facebookImage = MusicSonarUtils.loadBitmap(picURL, true);
                    MusicSonarUtils.getAccountID(MusicSonarConstant.accountName, MusicSonarConstant.facebookUID);
                } catch (JSONException e) {
                	Toast.makeText(context, "Facebook Error: " + e.getMessage(),  Toast.LENGTH_LONG).show();
                }
            }
        });
	}

	public static boolean verifyURL(String _url) throws Exception{
		String url_query = MusicSonarConstant.VERIFY_MP3_URL_LINK + "?url=" + _url;
		URL url = new URL(url_query);
		HttpURLConnection cnx = (HttpURLConnection)url.openConnection();
		cnx.setDoInput(true);
		cnx.setDoOutput(true);
		cnx.setRequestMethod("GET");

		InputStream in = cnx.getInputStream();
		StringBuffer json = new StringBuffer();
		int c;
		while ((c = in.read()) != -1) json.append((char) c);	
		in.close();

		JSONArray objArray = new JSONArray(json.toString());
		String estado = objArray.getJSONArray(0).getJSONObject(0).getString("estado");
		if("OK".equals(estado)){
			return true;
		}

		return false;
	}

	public static void setProcessMessage(MusicSonarDialog dialog, String message){
		dialog.setMessage(message);
	}

	public static void showToast(Context me, CharSequence message){
		Toast.makeText(me, message, Toast.LENGTH_LONG).show();
	}

	public static String convertToXMLString(PlayList _playList){
		XmlSerializer serializer = Xml.newSerializer();
		StringWriter writer = new StringWriter();
		try{
	        serializer.setOutput(writer);
	        serializer.startDocument("UTF-8", true);
	        serializer.startTag("", "songs-list");
	        for (Song item : _playList.getSongList()){
	        	serializer.startTag("", "song");
		        /**/
	        		serializer.startTag("", "songYT");
	        		serializer.text(item.getSongYT());
	        		serializer.endTag("", "songYT");
	        	/**/
	        	serializer.endTag("", "song");
	        }
	        serializer.endTag("", "songs-list");
	        serializer.endDocument();
	        return writer.toString();
		}catch(Exception e){
			Log.e("convertToXMLString", e.getMessage());
		}
 
		return null;
	}

	public static String convertToString(List<Song> songList){
		String result = "";
		for(Song song : songList){
			result += "* ";
			result += song.getSongTitle();
			result += " | ";
		}
		return result;
	}

	public static String getPlayListLink(){
		return "<a href=\""+ MusicSonarConstant.FACEBOOK_FEED_URL + "&list_id="+SongsManager.getActualPlayList().getCode().toString() + "\">" + SongsManager.getActualPlayList().getName() + "</a>";
	}
}